package com.zmn.oms.admin.controller.common;

import com.alibaba.fastjson.JSON;
import com.google.common.collect.Lists;
import com.zmn.base.common.data.common.dro.area.AreaDRO;
import com.zmn.base.common.data.common.dro.area.AreaSimpleDRO;
import com.zmn.base.product.common.consts.BaseProductConsts;
import com.zmn.base.product.common.dto.product.ProductBaseQuery;
import com.zmn.base.product.common.dto.product.ec.ProductBaseDRO;
import com.zmn.common.dto.VtDTO;
import com.zmn.common.dto2.Option;
import com.zmn.common.dto2.ResponseDTO;
import com.zmn.common.dto2.data.LayuiTableDO;
import com.zmn.common.utils.collection.CollectionUtil;
import com.zmn.common.utils.number.NumberUtil;
import com.zmn.common.utils.reflect.BeanMapper;
import com.zmn.consts.GlobalConsts;
import com.zmn.gms.common.dio.grid.online.grid.OnlineGridPageQuery;
import com.zmn.gms.common.dto.online.grid.GridBaseDRO;
import com.zmn.gms.dubbo.interfaces.grid.online.grid.GridListRemoteService;
import com.zmn.mcc.common.constant.DpermitConsts;
import com.zmn.mcc.common.dto.organize.OrganizeDRO;
import com.zmn.mcc.common.dto.permit.SpermitDTO;
import com.zmn.oms.admin.controller.order.OrderBaseController;
import com.zmn.oms.business.interfaces.work.OrderWorkPositionBService;
import com.zmn.oms.common.constant.OrderConsts;
import com.zmn.oms.common.dto.ResultDTO;
import com.zmn.oms.common.vo.KVDict;
import com.zmn.oms.model.dto.order.CheckServicePointDTO;
import com.zmn.oms.model.dto.product.ShowProductDTO;
import com.zmn.oms.model.vo.order.AreaVO;
import com.zmn.oms.model.vo.order.CheckServicePointVO;
import com.zmn.oms.model.vo.order.CompanyAreaPointVO;
import com.zmn.oms.model.vo.order.CompanyAreaVO;
import com.zmn.sp.common.model.available.AvailableAreaDRO;
import com.zmn.sp.common.model.available.SpAvailableAreaCheckDIO;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.dubbo.config.annotation.Reference;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 类描述：区域
 *
 * @author liuying
 * @date 2018/11/21 15:36
 */
@Controller
@RequestMapping("/area")
public class AreaController extends OrderBaseController {

    @Autowired
    OrderWorkPositionBService orderWorkPositionBService;
    @Reference(version = com.zmn.gms.dubbo.interfaces.utils.DubboConsts.INTERFACE_VERSION, check = false)
    private GridListRemoteService gridListRemoteService;

    /**
     * 获取父ID下的区域列表
     *
     * @return
     */
    @RequestMapping(value = "list", method = RequestMethod.GET)
    @ResponseBody
    public ResultDTO areaList(@RequestParam(value = "parentId", defaultValue = "1") Integer parentId) {
        return ResultDTO.success(super.getAreaListByPid(parentId));
    }

    /**
     * 获取父ID下的区域详情列表
     *
     * @return
     */
    @RequestMapping(value = "detail/list", method = RequestMethod.GET)
    @ResponseBody
    public ResultDTO areaDetailList(@RequestParam(value = "parentId", defaultValue = "1") Integer parentId) {
        return ResultDTO.success(super.getAreaDetailListByPid(parentId));
    }


    /**
     * 获取公司的城市列表
     *
     * @return
     */
    @RequestMapping(value = "company/city/list", method = RequestMethod.GET)
    @ResponseBody
    public ResultDTO cityListByCompanyId(Integer companyId) {
        ResponseDTO<List<VtDTO>> listResponseDTO = availableAreaListRemoteService.listCityVtByCompanyId(companyId);
        if (listResponseDTO.isSuccess() && listResponseDTO.getData() != null) {
            return ResultDTO.success(super.vt2VKDict(listResponseDTO.getData()));
        }
        return ResultDTO.success();
    }

    /**
     * 获取渠道开通城市列表
     *
     * @return
     */
    @RequestMapping(value = "channel/city/list", method = RequestMethod.GET)
    @ResponseBody
    public ResultDTO cityListByChannelId(Integer provinceId, Integer channelId, Integer showType) {

        // 获取所有城市
        List<KVDict> cityList;
        if (NumberUtil.isNullOrZero(provinceId)) {
            cityList = super.getCityListByDept();
        } else {
            cityList = super.getCityListByPidAndDept(provinceId);
        }
        if (CollectionUtils.isEmpty(cityList)) {
            return ResultDTO.success();
        }

        logger.info("cityListByChannelId(过滤前)-{}", cityList);

        if (channelId == null) {
            return ResultDTO.success(cityList);
        }

        // 查询渠道开通的城市，未设置返回全部
        ResponseDTO<List<AreaSimpleDRO>> listResponseDTO = channelAreaCategListRemoteService.listAreaByChannelId(channelId);
        logger.info("查询渠道开通城市列表出参：【{}】", JSON.toJSONString(listResponseDTO));
        List<AreaSimpleDRO> areaDTOList = listResponseDTO.getData();
        if (CollectionUtils.isEmpty(areaDTOList)) {
            return ResultDTO.success(cityList);
        }

        logger.debug("cityListByChannelId(渠道开通城市-channelId={})-{}", channelId, areaDTOList);

        // 过滤没有开通的城市ID
        Set<Integer> collect = areaDTOList.stream().map(AreaSimpleDRO::getCityId).collect(Collectors.toSet());
        cityList.removeIf(e -> !collect.contains(e.getValue()));

        return ResultDTO.success(cityList);
    }

    /**
     * 获取渠道开通城市列表
     *
     * @return
     */
    @RequestMapping(value = "check/channel_city", method = RequestMethod.GET)
    @ResponseBody
    public ResultDTO checkByChannelIdAndCityId(Integer cityId, Integer channelId, Integer showType) {
        if (channelId == null || cityId == null) {
            return ResultDTO.success();
        }

        ResponseDTO<List<AreaSimpleDRO>> listResponseDTO = channelAreaCategListRemoteService.listAreaByChannelId(channelId);
        List<AreaSimpleDRO> areaDTOList = listResponseDTO.getData();
        if (CollectionUtils.isEmpty(areaDTOList)) {
            return ResultDTO.success();
        }

        logger.debug("checkByChannelIdAndCityId->{}", areaDTOList);

        ResponseDTO<AreaDRO> areaDROResponseDTO = areaListRemoteService.getById(cityId);
        if (areaDROResponseDTO.getData() == null) {
            return ResultDTO.success();
        }

        String cityName = areaDROResponseDTO.getData().getName();

        // 过滤没有开通的城市ID
        boolean anyMatch = areaDTOList.stream().anyMatch(e -> Objects.equals(cityId, e.getCityId()));
        if (!anyMatch) {
            return ResultDTO.fail(String.format("当前渠道，未开通：%s", cityName));
        }

        // 判断数据权限
        SpermitDTO<Integer> spermitDTO = staffPermitRemoteService.listDpermitByLoginStaff(this.getLoginStaff(), DpermitConsts.TYPE_AREA_CITY, false);
        List<Integer> cityList = spermitDTO.getItems();
        if (CollectionUtils.isEmpty(cityList)) {
            return ResultDTO.success();
        }

        if (cityList.contains(cityId)) {
            return ResultDTO.success();
        }

        return ResultDTO.fail(String.format("您没有%s数据权限", cityName));
    }

    /**
     * 获取开通省份下的城市列表
     *
     * @param provinceId 省份ID
     * @return
     */
    @RequestMapping(value = "city/list", method = RequestMethod.GET)
    @ResponseBody
    public ResultDTO cityList(Integer provinceId) {
        return ResultDTO.success(super.getAreaListByPid(provinceId));
    }


    /**
     * 模糊查询城市
     * @param keyWord
     * @param level
     * @param parentId
     * @return
     */
    @RequestMapping(value = "city/fuzzy/list", method = RequestMethod.GET)
    @ResponseBody
    public ResultDTO fuzzyCity(String keyWord, @RequestParam(name = "level", defaultValue = "3", required = false) Integer level, @RequestParam(name = "parentId", required = false) Integer parentId) {
        return ResultDTO.success(super.fuzzyGetArea(keyWord, level, parentId));
    }

    /**
     * 获取开通省份下的城市列表
     *
     * @param provinceId 省份ID
     * @return
     */
    @RequestMapping(value = "permit/city/list", method = RequestMethod.GET)
    @ResponseBody
    public ResultDTO permitCityList(Integer provinceId) {
        return ResultDTO.success(super.getCityListByPidAndDept(provinceId));
    }

    /**
     * 获取开通省份下的城市列表
     *
     * @return
     */
    @RequestMapping(value = "city/all/list", method = RequestMethod.GET)
    @ResponseBody
    public ResultDTO cityList() {
        return ResultDTO.success(super.getAllCityList());
    }

    /**
     * 获取公司开通城市下的区域列表
     *
     * @param cityIdList 城市IDList
     * @return
     */
    @RequestMapping(value = "county/list", method = RequestMethod.POST)
    @ResponseBody
    public ResultDTO countyList(@RequestParam("cityIdList[]") Integer[] cityIdList) {
        List<KVDict> vtList = getCountListByCityIdsDept(cityIdList);
        if (CollectionUtils.isNotEmpty(vtList)) {
            return ResultDTO.success(vtList);
        } else {
            //未配置数据权限则返回全部区县
            ResponseDTO<List<Option<Integer>>> vtResponseDTO = areaListRemoteService.listOptionCountryByCityIds(new ArrayList(Arrays.asList(cityIdList)));
            if (vtResponseDTO.isSuccess() && vtResponseDTO.getData() != null) {
                return ResultDTO.success(super.option2VKDict(vtResponseDTO.getData()));
            }
        }
        return ResultDTO.success();
    }

    /**
     * 获取公司开通城市下的区域列表
     *
     * @param cityIdList 城市IDList
     * @return
     */
    @RequestMapping(value = "permit/county/list", method = RequestMethod.POST)
    @ResponseBody
    public ResultDTO permitCountyList(@RequestParam("cityIdList[]") Integer[] cityIdList) {
        return ResultDTO.success(getCountListByCityIdsDept(cityIdList));
    }

    /**
     * 获取公司服务坐标范围
     *
     * @param plat 平台标识
     * @param cityId 城市Id
     * @param productShowType 前台产品
     * @return
     */
    @RequestMapping(value = "point/list", method = RequestMethod.GET)
    @ResponseBody
    public ResultDTO pointList(Integer plat, Integer cityId, Integer productId, @RequestParam(value = "productShowType", defaultValue = "1") Integer productShowType) {
        if (!Objects.equals(plat, GlobalConsts.PLAT_MARK_ZMN)) {
            return ResultDTO.success();
        }

        // 产品Id为空 直接返回
        if (NumberUtil.isNullOrZero(productId)) {
            return ResultDTO.success();
        }

        List<AvailableAreaDRO> list;
        ResponseDTO<List<AvailableAreaDRO>> companyAreaResponseDTO = null;
        if (Objects.equals(productShowType, BaseProductConsts.EC_SHOW_TYPE)) {
            // 传递的前端产品，可能是后台产品
            ProductBaseQuery productDIO = new ProductBaseQuery();
            productDIO.setProductId(productId);
            ResponseDTO<List<ProductBaseDRO>> productRemote = productForeignListRemoteService.listBaseDROByQuery(productDIO);
            if (CollectionUtil.isNotNullOrEmpty(productRemote.getData()) && Objects.equals(BaseProductConsts.EC_SHOW_TYPE, productRemote.getData().get(0).getShowType())) {
                logger.info("传递前台产品[{}]，实际为后台产品", productId);
                companyAreaResponseDTO = serviceRuleListRemoteService.listByPlatAndCityAndShowProductId(plat, cityId, productId);
            }
        }
        if (Objects.isNull(companyAreaResponseDTO)) {
            companyAreaResponseDTO = serviceRuleListRemoteService.listByPlatAndCityAndProductId(plat, cityId, productId);
        }
        if (Objects.isNull(companyAreaResponseDTO)) {
            return ResultDTO.success();
        }
        list = companyAreaResponseDTO.getData();
        if (CollectionUtils.isEmpty(list)) {
            return ResultDTO.success();
        }

        List<CompanyAreaVO> companyAreaList = Lists.newArrayList();

        // 子公司，仅返回子公司服务范围
        try {
            // 查询用户所属组织架构
            ResponseDTO<OrganizeDRO> organDROResponseDTO = organizeListRemoteService.getByKey(getLoginStaff().getOrgId());
            OrganizeDRO organDRO = organDROResponseDTO.getData();
            if (organDRO != null) {
                boolean isSubCompany = organDRO.getLevel() == null || organDRO.getLevel() > GlobalConsts.LEVEL_2;
                Integer companyId = organDRO.getCompanyId();
                if (isSubCompany && Objects.nonNull(companyId)) {
                    // 分公司 权限，过滤工程师
                    list = list.stream().filter(item -> companyId.equals(item.getSubCompanyId())).collect(Collectors.toList());
                }
            }
        } catch (Exception ex) {
        }

        CompanyAreaVO companyAreaVO = new CompanyAreaVO();
        companyAreaVO.setCompanyId(list.get(0).getSubCompanyId());
        companyAreaVO.setCompanyName(list.get(0).getSubCompanyName());
        companyAreaVO.setCompanyFullName(list.get(0).getSubCompanyName());
        companyAreaVO.setPointList(BeanMapper.mapList(list, CompanyAreaPointVO.class));
        return ResultDTO.success(companyAreaList);
    }

    /**
     * 通过经纬度获取区域信息
     *
     * @param longitude
     * @param latitude
     * @return
     */
    @RequestMapping(value = "getCountyByPoint", method = RequestMethod.GET)
    @ResponseBody
    public ResultDTO getCounty(String longitude, String latitude) {
        ResponseDTO<AreaDRO> responseDTO = areaListRemoteService.getAreaByLatAndLng(Double.parseDouble(longitude), Double.parseDouble(latitude));
        AreaDRO areaDRO = responseDTO.getData();
        if (areaDRO == null) {
            return ResultDTO.fail("区域信息不存在");
        }

        AreaVO areaVO = new AreaVO();
        areaVO.setAreaId(areaDRO.getAreaId());
        areaVO.setAreaName(areaDRO.getName());
        return ResultDTO.success(areaVO);
    }

    /**
     * county
     * 判断服务范围
     * @param checkServicePointDTO
     * @return
     */
    @RequestMapping(value = "checkServicePoint", method = RequestMethod.GET)
    @ResponseBody
    public ResultDTO checkServicePoint(CheckServicePointDTO checkServicePointDTO) {

        Integer cityId = null;
        Integer countyId = checkServicePointDTO.getCountyId();
        String countyName = "";
        if (NumberUtil.isNullOrZero(countyId)) {
            ResponseDTO<AreaDRO> areaResponseDTO = areaListRemoteService.getAreaByLatAndLng(checkServicePointDTO.getLongitude(), checkServicePointDTO.getLatitude());
            AreaDRO areaDRO = areaResponseDTO.getData();
            if (areaDRO == null) {
                return ResultDTO.fail(areaResponseDTO.getMessage());
            }
            countyId = areaDRO.getCountyId();
            countyName = areaDRO.getCountyName();
            cityId = areaDRO.getCityId();
        } else {
            logger.info("areaListRemoteService.getById-{}", countyId);
            ResponseDTO<AreaDRO> areaResponseDTO = areaListRemoteService.getById(countyId);
            logger.info("areaListRemoteService.areaResponseDTO-{}", areaResponseDTO);
            AreaDRO areaDRO = areaResponseDTO.getData();
            if (areaDRO == null) {
                return ResultDTO.fail(areaResponseDTO.getMessage());
            }
            countyId = areaDRO.getAreaId();
            countyName = areaDRO.getName();
            cityId = areaDRO.getParentId();
        }

        // 总部用户或返修单不验证服务范围
        if (!super.isBranchCompany() || Objects.equals(OrderConsts.ORDER_TYPE_REWORK, checkServicePointDTO.getType()) ) {
            CheckServicePointVO build = CheckServicePointVO.builder()
                    .cityId(cityId)
                    .countyId(countyId)
                    .countyName(countyName)
                    .status(GlobalConsts.YES)
                    .build();
            logger.debug("checkServicePoint response-{}", build);
            return ResultDTO.success(build);
        }

        ShowProductDTO showProductDTO = super.getShowProductIdByProductId(checkServicePointDTO.getProductId());
        if (Objects.isNull(showProductDTO)) {
            return ResultDTO.fail("未找到产品信息");
        }

        // 子公司用户检测服务范围
        SpAvailableAreaCheckDIO spAvailableAreaCheckDIO = new SpAvailableAreaCheckDIO();
        spAvailableAreaCheckDIO.setBizType(checkServicePointDTO.getBizType());
        spAvailableAreaCheckDIO.setBizCompanyId(super.getOrgCompanyId());
        spAvailableAreaCheckDIO.setShowProductId(showProductDTO.getShowProductId());
        spAvailableAreaCheckDIO.setCountyId(countyId);
        spAvailableAreaCheckDIO.setLongitude(checkServicePointDTO.getLongitude());
        spAvailableAreaCheckDIO.setLatitude(checkServicePointDTO.getLatitude());
        logger.debug("checkServicePoint :dio={}", JSON.toJSONString(spAvailableAreaCheckDIO));
        ResponseDTO<Boolean> booleanResponseDTO = availableAreaListRemoteService.checkSpAvailableArea(spAvailableAreaCheckDIO);
        logger.debug("checkServicePoint :dro={}", booleanResponseDTO);
        int status = (booleanResponseDTO.isSuccess() && Objects.equals(booleanResponseDTO.getData(), Boolean.TRUE)) ? GlobalConsts.YES : GlobalConsts.NO;
        CheckServicePointVO build = CheckServicePointVO.builder()
                .cityId(cityId)
                .countyId(countyId)
                .countyName(countyName)
                .status(status)
                .build();
        return ResultDTO.success(build);
    }

    /**
     * county
     * 根据经纬度获取区域ID
     * @param longitude
     * @param latitude
     * @return
     */
    @RequestMapping(value = "getAreaInfo", method = RequestMethod.GET)
    @ResponseBody
    public ResultDTO checkServicePoint(Double longitude, Double latitude) {
        ResponseDTO<AreaDRO> areaResponseDTO = areaListRemoteService.getAreaByLatAndLng(longitude, latitude);
        AreaDRO areaDRO = areaResponseDTO.getData();
        if (areaDRO == null) {
            return ResultDTO.fail(areaResponseDTO.getMessage());
        }

        return ResultDTO.success(areaDRO);
    }

    /** @Author wangyanci
     * @Description 根据条件查询匹配小区
     * @Date 18:23 2021/4/6
     * @Param [cityId 市id, cityName 市名称, queryStr 查询字符串]
     * @return com.zmn.oms.common.dto.ResultDTO
     **/
    @RequestMapping(value = "queryCommunity", method = RequestMethod.GET)
    @ResponseBody
    public ResultDTO queryCommunity(Integer cityId, String cityName, String queryStr) {
        try {

        } catch (Exception ex) {
            ex.printStackTrace();
        }

        return ResultDTO.fail("小区库异常，使用标准百度地址");
    }

    /**
     * 网格列表查询
     *
     * @param query
     * @return
     */
    @PostMapping(value = "listPageGrid")
    @ResponseBody
    public ResultDTO listGrid(@RequestBody OnlineGridPageQuery query) {
        if (CollectionUtils.isEmpty(query.getCityIdList())) {
            LayuiTableDO<GridBaseDRO> data = new LayuiTableDO<>();
            data.setCount(0);
            data.setData(Lists.newArrayList());
            return ResultDTO.success(data);
        }

        logger.debug("AreaController.listGrid 入参【{}】", query);
        ResponseDTO<List<GridBaseDRO>> responseDTO = gridListRemoteService.listPageGridByQuery(query);
        logger.debug("AreaController.listGrid 出参【{}】", responseDTO);
        ResponseDTO<Integer> integerResponseDTO = gridListRemoteService.countGridByQuery(query);
        LayuiTableDO<GridBaseDRO> data = new LayuiTableDO<>();
        data.setCount(integerResponseDTO.getData());
        data.setData(responseDTO.getData());

//        LayuiTableDO<GridBaseDRO> data = new LayuiTableDO<>();
//        data.setCount(100);
//
//        GridBaseDRO gridBaseDRO = new GridBaseDRO();
//        gridBaseDRO.setGridId(1);
//        gridBaseDRO.setGridName("1");
//
//        GridBaseDRO gridBaseDRO1 = new GridBaseDRO();
//        gridBaseDRO1.setGridId(2);
//        gridBaseDRO1.setGridName("2");
//
//        GridBaseDRO gridBaseDRO3 = new GridBaseDRO();
//        gridBaseDRO1.setGridId(3);
//        gridBaseDRO1.setGridName("3");
//        data.setData(Lists.newArrayList(gridBaseDRO, gridBaseDRO1, gridBaseDRO3));
        return ResultDTO.success(data);
    }

}
